home *** CD-ROM | disk | FTP | other *** search
/ The Arsenal Files 8 / The Arsenal Files Collection #8 (Arsenal Computer) (1996).ISO / prg_casm / snpd9611.zip / FSM.C < prev    next >
C/C++ Source or Header  |  1996-11-24  |  3KB  |  109 lines

  1. .I 0 106
  2. /* +++Date last modified: 13-Aug-1996 */
  3.  
  4. /* =======================================================================
  5.     FSM.c           Finite State machines.
  6.                     Version 0.22x, 93-08-05.
  7.  
  8.  _____              This version is Public Domain.
  9.  /_|__|             A.Reitsma, Delft, Nederland.
  10. /  | \  --------------------------------------------------------------- */
  11.  
  12. #include <stdlib.h>
  13. #include "defines.h"
  14. #include "fsm.h"
  15.  
  16. /* tmp definitions until error module is finished */
  17. #define MEMORY      -1
  18. #define Error(x)    return x
  19.  
  20. /*  --- Local definitions and data ------------------------------------ */
  21. struct state_info
  22. {
  23.     struct FSMstate_entry * table ;
  24.     int entries ;
  25. };
  26.  
  27. static int state ;      /* the machine's state or it's maximum in setup */
  28. static struct state_info * info ;  /* derived info in a handier format  */
  29.  
  30. /*  --- Setup and action functions ------------------------------------ */
  31.  
  32. int FSMsetup( struct FSMstate_entry * StateEntry )
  33. {
  34.     struct FSMstate_entry * Entry = StateEntry ;
  35.     struct state_info * data ;
  36.  
  37.     /*  Find 'highest' state number. Negative number is end of list.
  38.         Gaps allowed. Must be sorted on state number in current version.
  39.         Prepared for non-sorted version though.
  40.     */
  41.     state = 0 ;
  42.     do
  43.     {
  44.         if( state < Entry->state )
  45.             state = Entry->state ;
  46.  
  47.     }while( (++Entry)->state >= 0 );
  48.  
  49.     /*  Create info 'array'
  50.     */
  51.     if( NULL == (info = MALLOC( state+1, struct state_info )))
  52.         Error( MEMORY );
  53.  
  54.     /*  Setup info 'array': split into sub-lists with size info.
  55.         First entry:
  56.     */
  57.     data = info ;
  58.     data->table = StateEntry ;
  59.     data->entries = 1 ;
  60.     /*  ... and the second and following entries:
  61.     */
  62.     while( (++StateEntry)->state >= 0 )
  63.     {
  64.         if( data->table->state == StateEntry->state )
  65.             data->entries ++ ;          /* same state */
  66.         else
  67.         {                               /* new state  */
  68.             data = info + StateEntry->state ;
  69.             data->table = StateEntry ;
  70.             data->entries = 1 ;
  71.         }
  72.     }
  73.  
  74.     state = 0 ; /* initial state for state machine */
  75.  
  76.     return 0 ;
  77. }
  78.  
  79. int FSMaction( int Cond )
  80. {
  81.     int count ;
  82.     struct FSMstate_entry * Table = info[ state ].table ;
  83.  
  84.     /*  Find matching condition in second or higher entry in table.
  85.     */
  86.     for( count = 1 ; count < info[ state ].entries ; count ++ )
  87.     {
  88.         Table ++;
  89.         if( Cond == Table->cond )
  90.         {
  91.             state = Table->next ;      /* match found: adjust state,    */
  92.                                        /* and execute non-NULL funtion. */
  93.             if( NULL != Table->action )
  94.                 return Table->action( Cond );
  95.             else
  96.                 return 0 ;
  97.         }
  98.     }
  99.  
  100.     /*  No matching condition found: use first entry as default action.
  101.     */
  102.     Table = info[ state ].table ;
  103.     state = Table->next ;
  104.     return Table->action( Cond );
  105. }
  106.  
  107. /* === FSM.c ========================================================== */
  108. .D 1 37
  109.